package com.hb.gp.util.tools;

import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.hb.gp.util.MsgGenUtil;

public class DES {

	static {
		Security.addProvider(new BouncyCastleProvider());
	}

	final static String PROVIDER_NAME = "BC";

	// des ecb
	public static String encryptDES_ECB(String encryptString, String encryptKey) {
		try {
			SecretKeySpec key = new SecretKeySpec(getKey(encryptKey), "DES");
			Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding",
					PROVIDER_NAME);
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] encryptedData = cipher.doFinal(MsgGenUtil
					.BCD2Bytes(encryptString));
			return MsgGenUtil.buf2hex(encryptedData);
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

	public static String decryptDES_ECB(String decryptString, String decryptKey) {
		try {
			SecretKeySpec key = new SecretKeySpec(getKey(decryptKey), "DES");
			Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding",
					PROVIDER_NAME);
			cipher.init(Cipher.DECRYPT_MODE, key);
			byte decryptedData[] = cipher.doFinal(MsgGenUtil
					.BCD2Bytes(decryptString));
			return new String(decryptedData);
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

	public static String encryptDES_CBC(String encryptString, String encryptKey) {
		try {
			SecretKeySpec key = new SecretKeySpec(getKey(encryptKey), "DES");
			Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding",
					PROVIDER_NAME);
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] encryptedData = cipher.doFinal(MsgGenUtil
					.BCD2Bytes(encryptString));
			return MsgGenUtil.buf2hex(encryptedData);
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

	public static byte[] encryptDES_CBC(byte[] src, byte[] enckey) {
		try {
			SecretKeySpec key = new SecretKeySpec(getKey(enckey), "DES");
			Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding",
					PROVIDER_NAME);
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] encryptedData = cipher.doFinal(src);
			return encryptedData;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String decryptDES_CBC(String decryptString, String decryptKey) {
		try {
			SecretKeySpec key = new SecretKeySpec(getKey(decryptKey), "DES");
			Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding",
					PROVIDER_NAME);
			cipher.init(Cipher.DECRYPT_MODE, key);
			byte decryptedData[] = cipher.doFinal(MsgGenUtil
					.BCD2Bytes(decryptString));
			return new String(decryptedData);
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

	public static byte[] getKey(String keyRule) {
		return getKey(MsgGenUtil.BCD2Bytes(keyRule));

	}

	public static byte[] getKey(byte[] keyByte) {
		Key key = null;
		byte[] byteTemp = new byte[8];
		for (int i = 0; i < byteTemp.length && i < keyByte.length; i++) {
			byteTemp[i] = keyByte[i];
		}
		key = new SecretKeySpec(byteTemp, "DES");
		return key.getEncoded();
	}

	public static String encryptTDES_ECB(String keybyte, String src) {
		try {
			return encryptTDES_ECB(MsgGenUtil.BCD2Bytes(keybyte),
					MsgGenUtil.BCD2Bytes(src));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String encryptTDES_ECB(byte[] keybyte, byte[] src) {
		try {

			byte[] keyFull = new byte[24];
			System.arraycopy(keybyte, 0, keyFull, 0, 16);
			System.arraycopy(keybyte, 0, keyFull, 16, 8);
			DESedeKeySpec dks = new DESedeKeySpec(keyFull);
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(
					"DESede", PROVIDER_NAME);
			SecretKey securekey = keyFactory.generateSecret(dks);
			Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding",
					PROVIDER_NAME);
			cipher.init(Cipher.ENCRYPT_MODE, securekey);
			byte[] retByte = cipher.doFinal(src);
			return MsgGenUtil.buf2hex(retByte);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String decryptTDES_ECB(byte[] keybyte, byte[] src) {
		try {

			byte[] keyFull = new byte[24];
			System.arraycopy(keybyte, 0, keyFull, 0, 16);
			System.arraycopy(keybyte, 0, keyFull, 16, 8);
			DESedeKeySpec dks = new DESedeKeySpec(keyFull);
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(
					"DESede", PROVIDER_NAME);
			SecretKey securekey = keyFactory.generateSecret(dks);
			Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding",
					PROVIDER_NAME);
			cipher.init(Cipher.DECRYPT_MODE, securekey);
			byte[] retByte = cipher.doFinal(src);
			return MsgGenUtil.buf2hex(retByte);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String encryptTDS_CBC(byte[] keybyte, byte[] src) {
		try {
			byte[] keyFull = new byte[24];
			System.arraycopy(keybyte, 0, keyFull, 0, 16);
			System.arraycopy(keybyte, 0, keyFull, 16, 8);
			SecretKey deskey = new SecretKeySpec(keyFull, "DESede");
			Cipher c1 = Cipher.getInstance("DESede/CBC/NOPadding",
					PROVIDER_NAME);
			byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0 };
			c1.init(Cipher.ENCRYPT_MODE, deskey, new IvParameterSpec(iv));
			byte[] test = c1.doFinal(src);
			return MsgGenUtil.buf2hex(test);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	public static String decryptTDES_CBC(byte[] keybyte, byte[] src) {
		try {

			byte[] keyFull = new byte[24];
			System.arraycopy(keybyte, 0, keyFull, 0, 16);
			System.arraycopy(keybyte, 0, keyFull, 16, 8);
			DESedeKeySpec dks = new DESedeKeySpec(keyFull);
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(
					"DESede", PROVIDER_NAME);
			SecretKey securekey = keyFactory.generateSecret(dks);
			Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding",
					PROVIDER_NAME);
			cipher.init(Cipher.DECRYPT_MODE, securekey);
			byte[] retByte = cipher.doFinal(src);
			return MsgGenUtil.buf2hex(retByte);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * add by lj
	 * 
	 * @param keybyte
	 *            加密
	 * @param src
	 * @return
	 */
	public static String encrypt(byte[] keybyte, byte[] src) {
		try {
			byte[] keyFull = new byte[24];
			System.arraycopy(keybyte, 0, keyFull, 0, 16);
			System.arraycopy(keybyte, 0, keyFull, 16, 8);
			SecretKey deskey = new SecretKeySpec(keyFull, "DESede");
			Cipher c1 = Cipher.getInstance("DESede/ECB/NoPadding",
					PROVIDER_NAME);

			c1.init(Cipher.ENCRYPT_MODE, deskey);

			byte[] test = c1.doFinal(src);
			return MsgGenUtil.buf2hex(test);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	/**
	 * 解密
	 * 
	 * @param keybyte
	 * @param src
	 * @return
	 */
	public static String decrypt(byte[] keybyte, byte[] src) {
		try {
			byte[] keyFull = new byte[24];
			System.arraycopy(keybyte, 0, keyFull, 0, 16);
			System.arraycopy(keybyte, 0, keyFull, 16, 8);
			SecretKey deskey = new SecretKeySpec(keyFull, "DESede");
			Cipher c1 = Cipher.getInstance("DESede/ECB/NoPadding",
					PROVIDER_NAME);

			c1.init(Cipher.DECRYPT_MODE, deskey);

			byte[] test = c1.doFinal(src);
			return MsgGenUtil.buf2hex(test);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;

	}

	/**
	 * add by lj
	 * 
	 * @param keybyte
	 *            加密
	 * @param src
	 * @return
	 */
	public static String encrypt8key(byte[] keybyte, byte[] src) {
		try {
			SecureRandom sr = new SecureRandom();
			DESKeySpec dks = new DESKeySpec(keybyte);
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			SecretKey securekey = keyFactory.generateSecret(dks);
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
			byte[] test = cipher.doFinal(src);
			return MsgGenUtil.buf2hex(test);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	public static void main(String[] args) {
		String src = "3132333435362020";
		String key = "0D094492A28EFB5A2A7B7B76EACA1DB8";

		String msg = DES.encrypt(MsgGenUtil.BCD2Bytes(key),
				MsgGenUtil.BCD2Bytes(src));
		System.out.println(msg);
	}
}
